#!/bin/sh
#
# Copyright (C) 2012-2020  Etersoft
# Copyright (C) 2012-2020  Vitaly Lipatov <lav@etersoft.ru>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

epm_install_files_alt()
{
    local files="$*"
    [ -z "$files" ] && return

    # TODO: check read permissions
    # sudo test -r FILE
    # do not fallback to install_names if we have no permissions

    __epm_print_warning_for_nonalt_packages $files

    # do repack if needed
    if __epm_repack_if_needed $files ; then
        [ -n "$repacked_pkgs" ] || fatal "Can't convert $files"
        files="$repacked_pkgs"
    fi

    if [ -n "$save_only" ] ; then
        echo
        cp -v $files "$EPMCURDIR"
        return
    fi

    if [ -n "$put_to_repo" ] ; then
        load_helper epm-repopkg
        epm_put_to_repo $files
        return
    fi

    __epm_check_if_src_rpm $files

    if [ -z "$repacked_pkgs" ] ; then
        __epm_check_vendor $files
        __epm_check_if_needed_repack $files
    fi

    # --replacepkgs: Install the Package Even If Already Installed
    local replacepkgs="$(__epm_get_replacepkgs $files)"
    sudocmd rpm -Uvh $replacepkgs $(subst_option dryrun --test) $force $noscripts $nodeps $files && save_installed_packages $files && return
    local RES=$?
    # TODO: check rpm result code and convert it to compatible format if possible
    __epm_check_if_rpm_already_installed $force $replacepkgs $noscripts $nodeps $files && return

    # if run with --nodeps, do not fallback on hi level
    [ -n "$nodeps" ] && return $RES

    # separate second output
    info

    # try install via apt if we could't install package file via rpm (we guess we need install requirements firsly)

    if [ -z "$noscripts" ] ; then
        epm_install_names $files
        return
    fi

    # TODO: use it always (apt can install version from repo instead of a file package)
    info "Workaround for install packages via apt with --noscripts (see https://bugzilla.altlinux.org/44670)"
    info "Firstly install package requrements …"
    # names of packages to be installed
    local fl="$(epm print name for package $files)"
    local req="$(docmd epm req --short $files)" || return
    # exclude package names from requires (req - fl)
    req="$(estrlist exclude "$fl" "$req")"
    # TODO: can we install only requires via apt?
    docmd epm install --skip-installed $req || return

    # retry with rpm
    # --replacepkgs: Install the Package Even If Already Installed
    local replacepkgs="$(__epm_get_replacepkgs $files)"
    sudocmd rpm -Uvh $replacepkgs $(subst_option dryrun --test) $force $noscripts $nodeps $files && save_installed_packages $files
}

get_current_kernel_flavour()
{
    rrel=$(uname -r)
    rflv=${rrel#*-}
    rflv=${rflv%-*}
    echo "$rflv"
}

# std-def 1.2.3-alt1 -> 1.2.3-std-def-alt1
make_kernel_release()
{
    echo "$2" | sed -e "s|-|-$1-|"
}

# return latest installed kernel in a form like 5.15.109-un-def-alt1
get_latest_kernel_rel()
{
    local kernel_flavour="$1"
    # current
    rrel=$(uname -r)

    # latest
    # copied and modified from update-kernel
    # get the maximum available kernel package version
    kmaxver=
    while read version
    do
        comparever="$(rpmevrcmp "$kmaxver" "$version")"
        [ "$comparever" -lt 0 ] && kmaxver="$version" ||:
    done <<<"$(epm print version-release for package kernel-image-$kernel_flavour)"
    [ -z "$kmaxver" ] && echo "$rrel" && return

    make_kernel_release "$kernel_flavour" "$kmaxver"
}

# install <module-name>-std-def
epm_install_alt_kernel_module()
{
    [ -n "$1" ] || return 0

    local kflist=''
    local kmplist=''
    local kmf km kf

    # fill kernel flavour list
    for kmf in $*; do
        km="$(echo "$kmf" | cut -d- -f1)"
        kf="$(echo "$kmf" | cut -d- -f2,3)"
        # use current flavour as default
        [ "$km" = "$kf" ] && kf="$(get_current_kernel_flavour)"
        kflist="$kflist $kf"
    done

    # firstly, update all needed kernels (by flavour)
    for kf in $(estrlist uniq $kflist) ; do
        info
        docmd epm update-kernel -t $kf || exit
    done

    # skip install modules if there are no installed kernels (may be, a container)
    epm installed "kernel-image-$kf" || return 0

    # make list for install kernel modules
    for kmf in $*; do
        km="$(echo "$kmf" | cut -d- -f1)"
        kf="$(echo "$kmf" | cut -d- -f2,3)"
        # use current flavour as default
        [ "$km" = "$kf" ] && kf="$(get_current_kernel_flavour)"
        kvf="$(get_latest_kernel_rel $kf)"
        #kmplist="$kmplist kernel-modules-$km-$kf"
        # install kernel module for latest installed kernel
        kmplist="$kmplist kernel-modules-$km-$kvf"
    done

    # secondly, install module(s)
    epm_install_names $kmplist
}


epm_install_alt_names()
{
    local kmlist=''
    local installnames=''

    while [ -n "$1" ] ; do
        local pkgname
        pkgname="$1"
        if echo "$pkgname" | grep -v "#" | grep -q "^kernel-modules*-" ; then
            # virtualbox[-std-def]
            local kmn="$(echo $pkgname | sed -e 's|kernel-modules*-||')"
            local kf1="$(echo "$kmn" | cut -d- -f2)"
            local kf2="$(echo "$kmn" | cut -d- -f4)"
            # pass install with full pkgnames
            if [ "$kf1" != "$kf2" ] && [ -n "$kf2" ] || echo "$kf1" | grep -q "^[0-9]" ; then
                installnames="$installnames $pkgname"
            else
                kmlist="$kmlist $kmn"
            fi
        else
            installnames="$installnames $pkgname"
        fi
        shift
    done

    epm_install_names $installnames || return
    epm_install_alt_kernel_module $kmlist || return
}


# apt-repo with non_interactive support
apt_repo_prepare()
{
    assure_exists apt-repo
    [ -n "$non_interactive" ] || return

    set_sudo
    trap "$SUDO rm /etc/apt/apt.conf.d/eepm-apt-noninteractive.conf 2>/dev/null" EXIT
    echo 'APT::Get::Assume-Yes "true";' | $SUDO tee /etc/apt/apt.conf.d/eepm-apt-noninteractive.conf >/dev/null
}

apt_repo_after()
{
    [ -n "$non_interactive" ] || return

    $SUDO rm /etc/apt/apt.conf.d/eepm-apt-noninteractive.conf 2>/dev/null
}


epm_install_alt_tasks()
{
    local res
    # TODO: don't use apt-repo
    apt_repo_prepare

    sudocmd_foreach "apt-repo test" $(tasknumber "$@")
    res=$?

    apt_repo_after
    return $res
}
